BaseEndpoint.page   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 11
c 0
b 0
f 0
rs 10
cc 2
1
import * as request from 'request-promise-native';
2
import { RequestError } from '../classes/RequestError';
3
import { EndpointConfiguration } from '../interfaces/common/EndpointConfiguration';
4
5
export interface QueryParameters {
6
    [key: string]: any;
7
}
8
9
export interface QueryDateLimiter {
10
    start_date?: string;
11
    end_date?: string;
12
}
13
14
/**
15
 * Abstract BaseEndpoint Class
16
 */
17
export abstract class BaseEndpoint {
18
19
    /**
20
     * Currently selected page
21
     * @var number
22
     */
23
    protected pageNumber: number = 1;
24
25
    /**
26
     * Language used to fetch data
27
     * @var string
28
     */
29
    protected selectedLanguage: string = 'en-US';
30
31
    /**
32
     * Default endpoint constructor
33
     * @param configuration
34
     */
35
    public constructor(private configuration: EndpointConfiguration) {}
36
37
    /**
38
     * Get results from the specified page
39
     * @param page
40
     * @return BaseEndpoint|self|this
41
     */
42
    public page(page: number): this {
43
        if (page > 0 && page <= 1000) {
44
            this.pageNumber = page;
45
        }
46
        return this;
47
    }
48
49
    /**
50
     * Set the language for the API response
51
     * @param language
52
     */
53
    public language(language: string): this {
54
        this.selectedLanguage = language;
55
        return this;
56
    }
57
58
    /**
59
     * Send GET request to the API
60
     * @param path
61
     * @param parameters
62
     */
63
    protected sendGetRequest(path: string, parameters: QueryParameters = {}): Promise<any> {
64
        const url = this.buildRequestPath(path, parameters);
65
        return request({
66
            url,
67
            json: true,
68
        })
69
            .then((json: any) => json)
70
            .catch(({ error }: any) => {
71
                const requestUrl = this.buildRequestPath(path, parameters, true);
72
                throw new RequestError(error.status_code, error.status_message, requestUrl);
73
            });
74
    }
75
76
    /**
77
     * Build proper request path and append passed parameters
78
     * @param { string } path
79
     * @param { QueryParameters } parameters
80
     * @param { boolean } omitAPIKey
81
     */
82
    private buildRequestPath(path: string, parameters: QueryParameters, omitAPIKey: boolean = false): string {
83
        const requestPath = `${this.configuration.host}/${path}`;
84
        const parametersArray: string[] = [];
85
        if (omitAPIKey === false) {
86
            parametersArray.push(`${encodeURIComponent('api_key')}=${encodeURIComponent(this.configuration.key)}`);
87
        }
88
89
        const imageLanguages: [string] = ['en'];
90
        const { selectedLanguage } = this;
91
92
        parameters.page = this.pageNumber;
93
        parameters.adult = this.configuration.adult;
94
        parameters.language = selectedLanguage;
95
96
        if (selectedLanguage.indexOf('-') !== -1) {
97
            const lang = selectedLanguage.substr(0, selectedLanguage.indexOf('-')).toLowerCase();
98
            if (!imageLanguages.includes(lang)) {
99
                imageLanguages.push(lang);
100
            }
101
        }
102
        parameters.include_image_language = imageLanguages;
103
104
        Object.keys(parameters).forEach((key) => {
105
            if (parameters.hasOwnProperty(key)) {
106
                let value = parameters[key];
107
                if (Array.isArray(value)) {
108
                    value = value.join(',');
109
                    parametersArray.push(`${encodeURIComponent(key)}=${value}`);
110
                } else {
111
                    parametersArray.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
112
                }
113
            }
114
        });
115
116
        const requestPathWithParameters = requestPath + '?' + parametersArray.join('&');
117
        return requestPathWithParameters.replace(/\?+$/, '');
118
    }
119
120
}
121